package org.scboy.dbms.service.imp;

import java.util.List;

import org.scboy.coobi.sql.factory.EntityFactory;
import org.scboy.dbms.dao.BaseDictionaryInfoDao;
import org.scboy.dbms.dao.BaseDictionaryTypeValueDao;
import org.scboy.dbms.loads.LoadDictionary;
import org.scboy.dbms.service.DictionaryInfoService;
import org.scboy.utils.caches.dbms.entity.DictionaryEntity;
import org.scboy.utils.entitys.coobi.Model;
import org.scboy.utils.entitys.coobi.Page;
import org.scboy.utils.enums.coobi.OrderType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.hutool.core.util.StrUtil;

/**
 * 字典值业务类
 * @author yanghao
 *
 */
@Service
public class DictionaryInfoServiceImpl implements DictionaryInfoService {

	@Autowired
	EntityFactory factory;
	
	@Autowired
	LoadDictionary dicCache;
	
	/**
	 * 分页查询字典值
	 * @param model 查询参数
	 * @return 分页结果
	 */
	public Page page(Model model){
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		return dao.page(model);
	}
	
	public List<Model> childs(String code,String parentId){
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		List<Model> datas= dao.select(Model.create().add("code", code).add("parentId", parentId).orderBy("infoSort"));
		for (Model model : datas) {
			long count=dao.count(Model.create().add("code", code).add("parentId", model.getString("id")));
			if(count>0) {
				model.add("isLeaf", false);
				model.add("isParent", true);
			}else {
				model.add("isLeaf", true);
				model.add("isParent", false);
			}
		}
		return datas;
	}

	public List<Model> list(String code,String parentId){
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		Model query=Model.create().add("code", code).add("activity", true).orderBy("infoSort");
		if(StrUtil.isNotEmpty(parentId)){
			query.add("parentId", parentId);
		}
		return dao.select(query);
	}
	/**
	 * 新增字典值
	 * @param model
	 * @return
	 */
	public boolean add(Model model){
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		if(dao.count(Model.create().add("id", model.getString("id")))>0){
			return false;
		}
		Integer infoSort = dao.max(new String [] {"infoSort"}, Model.create().add("parentId",model.getString("parentId"))).getInt("infoSort");
		if (infoSort == null) {
			infoSort = 0;
		} else {
			infoSort++;
		}
		model.add("infoSort", infoSort);
		if(dao.insert(model)>0){
			
			//更新缓存
			dicCache.update(model.toEntity(DictionaryEntity.class));
			return true;
		}else{
			return false;
		}
	}

	public void getParents(String id,List<Model> result){
		Model model=get(id);
		if(model!=null){
			result.add(model);
			if(!"root".equals(model.getString("parentId"))){
				getParents(model.getString("parentId"), result);
			}
		}
	}
	/**
	 * 更新字典值
	 * @param model
	 * @return
	 */
	public boolean update(Model model){
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		//判断编码是否已经存在，不包含自己的编码。
		if(StrUtil.isEmpty(model.getString("id"))){
			return false;
		}
		if(dao.update(model)>0){
			//更新缓存
			dicCache.updateByKey(model.getString("id"));
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 删除字典值
	 * @param id
	 * @return
	 */
	@Transactional
	public boolean delete(String id){
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		BaseDictionaryTypeValueDao tvDao=factory.getDao(BaseDictionaryTypeValueDao.class);
		Model model=get(id);
		//如果存在子，先删除子。
		List<Model> children=list(model.getString("code"), model.getString("id"));
		for (Model child : children) {
			delete(child.getString("id"));
		}
		tvDao.delete(Model.create().add("infoId", id));
		int count=dao.delete(Model.create().add("id", id));
		if(count>0){
			//删除缓存
			dicCache.removeCache(id);
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 获取字典
	 * @param code
	 * @return
	 */
	public Model get(String id){
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		return dao.get(Model.create().add("id", id));
	}
	
	/**
	 * 启用禁用字典值
	 * @param id ID
	 * @return
	 */
	public boolean checkState(String id) {
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		Model model = get(id);
		if (model == null) {
			return false;
		}
		model.add("activity", !model.getBoolean("activity"));
		int resultCount = dao.update(model);
		if (resultCount > 0) {
			return true;
		} else {
			return false;
		}
	}
	
	@Transactional
	public boolean sort(String id, int type) {
		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		Model model=dao.get(Model.create().add("id", id));
		Model lastModel=null;
		String sortKey="infoSort";
		String idKey="id";
		//降序
		if(type==0) {
			//查询下面一个系统
			lastModel=dao.get(Model.create().GT(sortKey, model.getInt(sortKey)).add("parentId", model.getString("parentId")).orderBy(sortKey));
			
		}else {
			//升序
			lastModel=dao.get(Model.create().LT(sortKey, model.getInt(sortKey)).add("parentId", model.getString("parentId")).orderBy(sortKey,OrderType.DESC));
			
		}
		if(lastModel!=null) {
			dao.update(Model.create().add(sortKey, lastModel.getInt(sortKey)),Model.create().add(idKey, id));
			dao.update(Model.create().add(sortKey, model.getInt(sortKey)),Model.create().add(idKey, lastModel.getString(idKey)));
		}
		return true;
	}
	
	public List<Model> treeChildren(String code,String parentId,String childrenName,String value,String name) {

		BaseDictionaryInfoDao dao=factory.getDao(BaseDictionaryInfoDao.class);
		
		List<Model> list=dao.select(
				Model.create().add("parentId", parentId).add("activity", true).add("code", code).orderBy("infoSort")
		);
		for (Model model : list) {
			model.add(value, model.getString("id"));
			model.add(name, model.getString("name"));
			List<Model> children= treeChildren(code,model.getString("id"),childrenName,value,name);
			if(children.size()>0) {
				model.add("isLeaf", false);
				model.add("isParent", true);
				model.add(childrenName,children);
			}else {
				model.add("isLeaf", true);
				model.add("isParent", false);
			}
		}
		return list;
	}
}


